package com.jin10.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jin10.bean.BaseResponse;
import com.jin10.entity.ApiList;
import com.jin10.entity.Tag;
import com.jin10.mapper.TagMapper;
import com.jin10.service.IApiListService;
import com.jin10.service.ITagService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jin10.vo.TagTreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 标签表 服务实现类
 * </p>
 *
 * @author raofy
 * @since 2022-01-21
 */
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements ITagService {

    @Autowired
    IApiListService iApiListService;

    @Override
    public boolean recurrentDelete(Integer id) {
        List<Tag> tags = baseMapper.selectList(null);
        if (!tags.isEmpty()) {
            List<Integer> delete = returnAllSubclassesByRootId(tags, id);
            delete.add(id);
            return baseMapper.deleteBatchIds(delete) == 0 ? false : true;
        }
        return false;
    }


    @Override
    public List<TagTreeVo> getList() {
        ArrayList<TagTreeVo> result = new ArrayList<>();
        List<Tag> tagList = baseMapper.getTagList();
        List<Tag> root = tagList.stream().filter(tag -> tag.getParentId() == 0).collect(Collectors.toList());
        for (Tag tag : root) {
            Integer rootId = tag.getId();
            if (Objects.nonNull(rootId)) {
                TagTreeVo one = new TagTreeVo();
                one.setParentId(tag.getParentId());
                one.setSubclass(getTree(tagList, rootId));
                one.setName(tag.getName());
                one.setApis(tag.getApis());
                one.setId(rootId);
                result.add(one);
            }
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateElement(Tag dto) {
        boolean a = false;
        boolean b = false;
        Integer tagId = null;
        if (Objects.nonNull(dto.getName())) {
            List<ApiList> apis = new ArrayList<>();
            if (Objects.isNull(dto.getParentId())) {
                dto.setParentId(0);
            }
            if (Objects.isNull(dto.getId())) {
                tagId = baseMapper.insertOne(dto);
                a = tagId != 0 ? true : false;
            } else {
                a = baseMapper.updateById(dto) != 0 ? true : false;
            }
            if (dto.getApis() != null && !apis.isEmpty()) {
                for (ApiList api : apis) {
                    if (Objects.isNull(api.getId())) {
                        api.setTagId(tagId);
                        b = iApiListService.save(api);
                    } else {
                        b = iApiListService.updateById(api);
                    }
                }
            }
            return a && b;
        } else {
            return a && b;
        }
    }

    @Override
    public TagTreeVo getTagListByRootId(Integer id) {
        TagTreeVo result = null;
        List<Tag> tagList = baseMapper.getTagList();
        List<Tag> rootElementList = tagList.stream().filter(tag -> tag.getId().equals(id)).collect(Collectors.toList());

        if (rootElementList != null) {
            Tag root = rootElementList.get(0);
            result = new TagTreeVo();
            result.setParentId(root.getParentId());
            result.setSubclass(getTree(tagList, root.getId()));
            result.setName(root.getName());
            result.setApis(root.getApis());
            result.setId(root.getId());
        }
        return result;
    }


    public List<TagTreeVo> getTree(List<Tag> tagList, Integer rootId) {
        List<TagTreeVo> tagTreeVoList = new ArrayList<>();
        for (Tag tag : tagList) {
            if (tag.getParentId().equals(rootId)) {
                TagTreeVo tagTreeVo = new TagTreeVo();
                tagTreeVo.setId(tag.getId());
                tagTreeVo.setApis(tag.getApis());
                tagTreeVo.setName(tag.getName());
                tagTreeVo.setParentId(tag.getParentId());
                tagTreeVo.setSubclass(getTree(tagList, tag.getId()));
                tagTreeVoList.add(tagTreeVo);
            }
        }
        return tagTreeVoList;
    }

    public List<Integer> returnAllSubclassesByRootId(List<Tag> allTags, Integer rootId) {
        List<Integer> result = new ArrayList<>();
        result = recurrenceFind(allTags, rootId);
        return result;
    }

    public List<Integer> recurrenceFind(List<Tag> allTags, Integer parentId) {
        List<Integer> result = new ArrayList<>();
        for (Tag tag : allTags) {
            if (tag.getParentId().equals(parentId)) {
                result.add(tag.getId());
                result.addAll(recurrenceFind(allTags, tag.getId()));
            }
        }
        return result;
    }
}
